/*
 * Copyright 2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cc.siyecao.mapper.entity;

import cc.siyecao.mapper.provider.Caching;
import cc.siyecao.mapper.provider.entity.EntityInfoMapper;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Optional;

/**
 * 实体类基本方法
 *
 * @param <T>  实体类类型
 * @param <ID> 主键类型
 * @author liuzh
 */
public interface EntityMapper<T, ID> extends EntityInfoMapper<T> {

    /**
     * 保存实体
     *
     * @param entity 实体类
     * @return 1成功，0失败
     */
    @Lang(Caching.class)
    @InsertProvider(type = EntityProvider.class, method = "insert")
    int insert(T entity);

    /**
     * 保存实体中不为空的字段
     *
     * @param entity 实体类
     * @return 1成功，0失败
     */
    @Lang(Caching.class)
    @InsertProvider(type = EntityProvider.class, method = "insertSelective")
    int insertSelective(T entity);

    /**
     * 根据主键删除
     *
     * @param id 主键
     * @return 1成功，0失败
     */
    @Lang(Caching.class)
    @DeleteProvider(type = EntityProvider.class, method = "deleteById")
    int deleteById(ID id);

    /**
     * 保存实体信息批量删除
     *
     * @param entity 实体类
     * @return 大于等于1成功，0失败
     */
    @Lang(Caching.class)
    @DeleteProvider(type = EntityProvider.class, method = "delete")
    int delete(T entity);

    /**
     * 根据主键更新实体
     *
     * @param entity 实体类
     * @return 1成功，0失败
     */
    @Lang(Caching.class)
    @UpdateProvider(type = EntityProvider.class, method = "updateById")
    int updateById(T entity);

    /**
     * 根据主键更新实体中不为空的字段
     *
     * @param entity 实体类
     * @return 1成功，0失败
     */
    @Lang(Caching.class)
    @UpdateProvider(type = EntityProvider.class, method = "updateByIdSelective")
    int updateByIdSelective(T entity);

    /**
     * 根据主键查询实体
     *
     * @param id 主键
     * @return 实体
     */
    @Lang(Caching.class)
    @SelectProvider(type = EntityProvider.class, method = "selectById")
    Optional<T> selectById(ID id);

    /**
     * 根据实体字段条件查询唯一的实体
     *
     * @param entity 实体类
     * @return 单个实体，查询结果由多条时报错
     */
    @Lang(Caching.class)
    @SelectProvider(type = EntityProvider.class, method = "select")
    Optional<T> selectOne(T entity);

    /**
     * 根据实体字段条件批量查询
     *
     * @param entity 实体类
     * @return 实体列表
     */
    @Lang(Caching.class)
    @SelectProvider(type = EntityProvider.class, method = "select")
    List<T> selectList(T entity);

    /**
     * 根据实体字段条件查询总数
     *
     * @param entity 实体类
     * @return 总数
     */
    @Lang(Caching.class)
    @SelectProvider(type = EntityProvider.class, method = "count")
    long count(T entity);

}
